// flattenObject：以键的路径扁平化对象
// 使用递归。

// 利用Object.keys(obj)联合Array.prototype.reduce()，以每片叶子节点转换为扁平的路径节点。
// 如果键的值是一个对象，则函数使用调用适当的自身prefix以创建路径Object.assign()。
// 否则，它将适当的前缀键值对添加到累加器对象。
// prefix除非您希望每个键都有一个前缀，否则应始终省略第二个参数。
const flattenObject = (obj, prefix = '') =>
	Object.keys(obj).reduce((acc, k) => {
		const pre = prefix.length ? prefix + '.' : '';
		if (typeof obj[k] === 'object') {
			Object.assign(acc, flattenObject(obj[k], pre + k))
		}else {
			acc[pre + k] = obj[k]
		};
		return acc;
	}, {});

console.log(flattenObject({ a: { b: { c: 1 } }, d: 1 })); // { 'a.b.c': 1, d: 1 }

// unflattenObject：以键的路径展开对象
const unflattenObject = (obj) =>
	Object.keys(obj).reduce((acc, k) => {
		if (k.indexOf('.') !== -1) {
			const keys = k.split('.');
			Object.assign(
				acc,
				JSON.parse(
					'{' +
						keys.map((v, i) => (i !== keys.length - 1 ? `"${v}":{` : `"${v}":`)).join('') +
						obj[k] +
						'}'.repeat(keys.length)
				)
			);
		} else acc[k] = obj[k];
		return acc;
	}, {});``

console.log(unflattenObject({ 'a.b.c': 1, d: 1 })); // { a: { b: { c: 1 } }, d: 1 }
